diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-10-17 08:09:35 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-10-17 08:09:35 +0000 |
| commit | bea9853efe30c393b0d030bc552c1f5bbb838835 (patch) | |
| tree | 820e12543f847bbcdc8d55b575016c535fb299c6 /app/[lng]/evcp | |
| parent | 1540eac291761ffd8fc1947ed626e4e4a4407922 (diff) | |
(대표님) 데이터룸 관련 개발사항
Diffstat (limited to 'app/[lng]/evcp')
| -rw-r--r-- | app/[lng]/evcp/data-room/[projectId]/members/page.tsx | 41 | ||||
| -rw-r--r-- | app/[lng]/evcp/data-room/[projectId]/settings/page.tsx | 20 |
2 files changed, 34 insertions, 27 deletions
diff --git a/app/[lng]/evcp/data-room/[projectId]/members/page.tsx b/app/[lng]/evcp/data-room/[projectId]/members/page.tsx index 18442c0e..dbd5e37d 100644 --- a/app/[lng]/evcp/data-room/[projectId]/members/page.tsx +++ b/app/[lng]/evcp/data-room/[projectId]/members/page.tsx @@ -105,7 +105,7 @@ export default function ProjectMembersPage({ const [roleFilter, setRoleFilter] = useState<string>('all'); const [addMemberOpen, setAddMemberOpen] = useState(false); const [editingMember, setEditingMember] = useState<Member | null>(null); - + // 사용자 선택 관련 상태 const [availableUsers, setAvailableUsers] = useState<User[]>([]); const [selectedUser, setSelectedUser] = useState<User | null>(null); @@ -113,12 +113,12 @@ export default function ProjectMembersPage({ const [userPopoverOpen, setUserPopoverOpen] = useState(false); const [loadingUsers, setLoadingUsers] = useState(false); const [isExternalUser, setIsExternalUser] = useState(false); // 외부 사용자 여부 - + const [newMemberRole, setNewMemberRole] = useState<string>('viewer'); const [currentUserRole, setCurrentUserRole] = useState<string>('viewer'); const [page, setPage] = useState(1); const pageSize = 20; - + // Command component key management const userOptionIdsRef = useRef<Record<number, string>>({}); const popoverContentId = `popover-content-${Date.now()}`; @@ -284,7 +284,7 @@ export default function ProjectMembersPage({ const handleSelectUser = (user: User) => { setSelectedUser(user); setUserPopoverOpen(false); - + // 외부 사용자(partners)인 경우 역할을 viewer로 고정 if (user.domain === 'partners') { setIsExternalUser(true); @@ -319,6 +319,7 @@ export default function ProjectMembersPage({ user.email.toLowerCase().includes(userSearchTerm.toLowerCase()) ); + const canManageMembers = currentUserRole === 'owner' || currentUserRole === 'admin'; const totalPages = Math.max(1, Math.ceil(filteredMembers.length / pageSize)); @@ -577,7 +578,7 @@ export default function ProjectMembersPage({ <TabsContent value="internal" className="space-y-4 mt-4"> <div className="space-y-2"> <Label htmlFor="internal-user">사용자 선택</Label> - + {loadingUsers ? ( <div className="flex items-center justify-center py-4"> <Loader2 className="h-4 w-4 animate-spin" /> @@ -665,8 +666,8 @@ export default function ProjectMembersPage({ <div className="space-y-2"> <Label htmlFor="internal-role">역할</Label> - <Select - value={newMemberRole} + <Select + value={newMemberRole} onValueChange={setNewMemberRole} disabled={!selectedUser || isExternalUser} > @@ -685,14 +686,14 @@ export default function ProjectMembersPage({ <TabsContent value="external" className="space-y-4 mt-4"> <div className="rounded-lg bg-amber-50 border border-amber-200 p-3 mb-4"> <p className="text-sm text-amber-800"> - <strong>보안 정책 안내</strong><br/> + <strong>보안 정책 안내</strong><br /> 외부 사용자(파트너)는 보안 정책상 Viewer 권한만 부여 가능합니다. </p> </div> <div className="space-y-2"> <Label htmlFor="external-user">파트너 선택</Label> - + {loadingUsers ? ( <div className="flex items-center justify-center py-4"> <Loader2 className="h-4 w-4 animate-spin" /> @@ -723,7 +724,7 @@ export default function ProjectMembersPage({ <PopoverContent className="w-[460px] p-0"> <Command> <CommandInput - placeholder="이름으로 검색..." + placeholder="이름 또는 이메일로 검색..." value={userSearchTerm} onValueChange={setUserSearchTerm} /> @@ -738,7 +739,7 @@ export default function ProjectMembersPage({ <CommandEmpty>파트너를 찾을 수 없습니다.</CommandEmpty> <CommandGroup heading="파트너 목록"> {filteredUsers - .filter(u => u.domain === 'partners') + .filter(u => u.ownerCompanyId !== null) .map((user) => ( <CommandItem key={user.id} @@ -748,12 +749,14 @@ export default function ProjectMembersPage({ setIsExternalUser(true); setNewMemberRole('viewer'); }} - value={user.name} + value={`${user.name} ${user.email}`} className="truncate" > - <Users className="mr-2 h-4 w-4 text-amber-600" /> - <span className="truncate flex-1">{user.name}</span> - <Badge variant="outline" className="text-xs mx-2">파트너</Badge> + <Users className="mr-2 h-4 w-4 text-amber-600 flex-shrink-0" /> + <div className="flex-1 truncate"> + <div className="font-medium truncate">{user.name}</div> + <div className="text-xs text-muted-foreground truncate">{user.email}</div> + </div> <Check className={cn( "ml-auto h-4 w-4 flex-shrink-0", @@ -785,8 +788,8 @@ export default function ProjectMembersPage({ </Tabs> <DialogFooter> - <Button - variant="outline" + <Button + variant="outline" onClick={() => { setAddMemberOpen(false); setSelectedUser(null); @@ -797,8 +800,8 @@ export default function ProjectMembersPage({ > 취소 </Button> - <Button - onClick={addMember} + <Button + onClick={addMember} disabled={!selectedUser} > 추가하기 diff --git a/app/[lng]/evcp/data-room/[projectId]/settings/page.tsx b/app/[lng]/evcp/data-room/[projectId]/settings/page.tsx index aa0f3b52..fc132e65 100644 --- a/app/[lng]/evcp/data-room/[projectId]/settings/page.tsx +++ b/app/[lng]/evcp/data-room/[projectId]/settings/page.tsx @@ -2,7 +2,7 @@ // app/projects/[projectId]/settings/page.tsx 'use client'; -import { useState, useEffect } from 'react'; +import { useState, useEffect ,use} from 'react'; import { Settings, Shield, @@ -59,8 +59,12 @@ interface ProjectSettings { export default function ProjectSettingsPage({ params }: { - params: { projectId: string } + params: Promise<{ projectId: string }> }) { + + const { projectId } = use(params); + + const [settings, setSettings] = useState<ProjectSettings | null>(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); @@ -74,12 +78,12 @@ export default function ProjectSettingsPage({ useEffect(() => { fetchSettings(); checkUserRole(); - }, [params.projectId]); + }, [projectId]); const fetchSettings = async () => { try { setLoading(true); - const response = await fetch(`/api/projects/${params.projectId}/settings`); + const response = await fetch(`/api/projects/${projectId}/settings`); if (!response.ok) { throw new Error('설정을 불러올 수 없습니다'); @@ -100,7 +104,7 @@ export default function ProjectSettingsPage({ const checkUserRole = async () => { try { - const response = await fetch(`/api/projects/${params.projectId}/access`); + const response = await fetch(`/api/projects/${projectId}/access`); const data = await response.json(); setCurrentUserRole(data.role); } catch (error) { @@ -113,7 +117,7 @@ export default function ProjectSettingsPage({ try { setSaving(true); - const response = await fetch(`/api/projects/${params.projectId}/settings`, { + const response = await fetch(`/api/projects/${projectId}/settings`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(settings), @@ -138,7 +142,7 @@ export default function ProjectSettingsPage({ const deleteProject = async () => { try { - const response = await fetch(`/api/projects/${params.projectId}`, { + const response = await fetch(`/api/projects/${projectId}`, { method: 'DELETE', }); @@ -161,7 +165,7 @@ export default function ProjectSettingsPage({ const archiveProject = async () => { try { - const response = await fetch(`/api/projects/${params.projectId}/archive`, { + const response = await fetch(`/api/projects/${projectId}/archive`, { method: 'POST', }); |
